/**
 * 
 */
package com.jie.eclipse.pan.form.support;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.LinkedHashMap;
import java.util.List;

import com.jie.eclipse.pan.data.BaseDataEntity;
import com.jie.eclipse.pan.form.item.Script;
import com.jie.eclipse.pan.utils.StringBuilderEx;
import com.jie.eclipse.pan.utils.StringHelper;
import com.jie.eclipse.pan.utils.Utils;

/**
 * @author yanjie
 *
 */
public class FormItem {
	protected Hashtable arrListItem = null;//參數名稱
	protected LinkedHashMap extAttrList = null;// new Hashtable();
	protected int currentIndex = 0;//當前顯示到第幾個控件
	
	protected List<FormItem> items = null ;//所有子控件
	protected List<Script> script = null ;//所有子控件
	protected FormItem parentItem = null ;//父控件
	

	protected boolean enab = true;

	public static String TAG_ID = "id";
	public static String TAG_NODENAME = "NODENAME";
	public static String TAG_NODEVALUE = "NODEVALUE";
	public static String TAG_NAME = "name";
	public static String TAG_STYLE = "style";
	public static String TAG_CSS = "class";
	public static String TAG_WIDTH = "width";
	public static String TAG_HEIGHT = "height";
	public static String TAG_POS = "pos";//位置
	public static String TAG_INDEX = "0";//处理表单元素重复的时候,无法设置默认值的问题
	
	protected String strId = ""; // 节点ID
	protected String strNodeName = "";
	protected String strNodeValue = "";
	protected String strName = "";
	protected String strStyle = "";
	protected String strCss = "";
	protected String strWidth = "";
	protected String strHeight = "";
	protected int iPos = 0 ;
	protected int iIndex = 0 ;
	protected BaseDataEntity config = null;//导出配置
	protected boolean bNoBody = false;
	
	public BaseDataEntity getConfig(String strParam){
		BaseDataEntity temConfig = null;
		String strConfig = this.GetExtValue(strParam,"");
		if(!StringHelper.IsNullOrEmpty(strConfig)){
			try {
				temConfig = BaseDataEntity.FromJSONString(StringHelper.Format("{%1$s}",strConfig));
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
	
		if(temConfig == null) temConfig = new BaseDataEntity();
		return temConfig;
	}
	
	public BaseDataEntity getExportConfig(){
		if(config != null)
			return config;
		else{
			String strConfig = this.GetExtValue("exportconfig","");
			if(!StringHelper.IsNullOrEmpty(strConfig)){
				try {
					config = BaseDataEntity.FromJSONString(StringHelper.Format("{%1$s}",strConfig));
				} catch (Exception e) {
					e.printStackTrace();
				}
				
			}
		
			if(config == null) config = new BaseDataEntity();
		}
		return config;
	}
	
	protected boolean bFromTag = false ;//是否是tag生成的控件
	
	public void onRender(StringBuilderEx writer){
		outItemBegin(writer);
		if(!this.isNoBody()){
			outItemBody(writer);
			outItemEnd(writer);
		}
		
		
		if(this.getScript() != null && this.getScript().size()>0){
			//writer.write("<script>");
			for (int i = 0; i < this.getScript().size(); i++) {
				writer.Append(this.getScript().get(i).getNodeValue());
			}
			//writer.write("</script>");
		}
	}
	
//	public String toOutString2(){
//		StringWriter writer = new StringWriter();
//		onRender(writer);
//		return writer.toString();
//	}
	
	public void init(){
		
	}
	
	public void outItemBegin(StringBuilderEx writer){
		onOutItemBegin(writer);
	}
	
	/**
	 * 
	 */
	public void onOutItemBegin(StringBuilderEx writer) {
		if(this.getParentItem() != null){
			writer.Append("\r\n");
			
			for (int i = 0; i < this.getLev(); i++) {
				writer.Append("	");
			}
		}
		
		if(!StringHelper.IsNullOrEmpty(this.getNodeName())){
			writer.Append(StringHelper.Format("<%1$s",this.getNodeName()));
			AttributeBuilder attributesBuilder = new AttributeBuilder();
			attributesBuilder.InitFromHashtable(this.extAttrList,this.arrListItem,true);
			FillAttributeBuilder(attributesBuilder);
			writer.Append(attributesBuilder.ToOutputString());
			
			if(!this.isNoBody()){
				writer.Append(">");
			}else{
				writer.Append("/>");
			}
		}
	}
	
	public void outItemBodyHeader(StringBuilderEx writer,FormItem item){
		
	}
	
	public void outItemBodyFooter(StringBuilderEx writer,FormItem item){
		
	}
	
	public void outItemBody(StringBuilderEx writer){
		if(this.getItems()  == null || this.getItems().size() == 0){
			currentIndex++;
			onOutItemBody(writer,this,true);
		}else{
			for (int i = 0 ;i<this.getItems().size();i++) {
				Object object = this.getItems().get(i);
				if (object instanceof FormItem) {
					FormItem item = (FormItem) object;
					currentIndex++;
					onOutItemBody(writer,item,false);
				}
			}
		}
	}
	
	public void onOutItemBody(StringBuilderEx writer,FormItem item,boolean bRenderNodeValue){
		outItemBodyHeader(writer,item);
		if(bRenderNodeValue)
			onOutSingleBody(writer,item);
		else{
//			writer.Append("\r\n	");
			item.onRender(writer);
			//writer.Append("\r\n	");
		}
		outItemBodyFooter(writer,item);
	}
	
	public void onOutSingleBody(StringBuilderEx writer,FormItem item){
		writer.Append(item.getNodeValue());
	}
	
	public void outItemEnd(StringBuilderEx writer){
		onOutItemEnd(writer);
	}
	
	public void onOutItemEnd(StringBuilderEx writer){
		if(!StringHelper.IsNullOrEmpty(this.getNodeName())){
			if(this.getParentItem() != null && this.getItems() != null && this.getItems().size() > 0){
				writer.Append("\r\n");
				
				for (int i = 0; i < this.getLev(); i++) {
					writer.Append("	");
				}
			}
			writer.Append(StringHelper.Format("</%1$s>",this.getNodeName()));
		}
	}

	public void OnSetProperty(String strName, String strValue)
	{
		if (strName.compareToIgnoreCase(TAG_ID) == 0)
		{
			this.strId = strValue;
			return;
		}
		
		if (strName.compareToIgnoreCase(TAG_NODENAME) == 0)
		{
			this.strNodeName = strValue;
			return;
		}
		
		if (strName.compareToIgnoreCase(TAG_NODEVALUE) == 0)
		{
			this.strNodeValue = strValue;
			return;
		}
		
		
		if (strName.compareToIgnoreCase(TAG_NAME) == 0)
		{
			this.strName = strValue;
			return;
		}
		
		if (strName.compareToIgnoreCase(TAG_STYLE) == 0)
		{
			this.strStyle += strValue;
			return;
		}
		
		if (strName.compareToIgnoreCase(TAG_CSS) == 0)
		{
			this.strCss = strValue;
			return;
		}
		
		if (strName.compareToIgnoreCase(TAG_WIDTH) == 0)
		{
			this.strWidth = strValue;
			return;
		}
		
		if (strName.compareToIgnoreCase(TAG_HEIGHT) == 0)
		{
			this.strHeight = strValue;
			return;
		}
		
		if (strName.compareToIgnoreCase(TAG_POS) == 0)
		{
			this.iPos = StringHelper.GetValue(strValue,0);
			return;
		}
		
		if(arrListItem == null)
			arrListItem = new Hashtable();
		arrListItem.put(strName.toUpperCase(), strName);
		
		// 不明属性
		if (extAttrList == null)
			extAttrList = new LinkedHashMap();
		
		//_static 不转为大写 ,保持原大小写不变
		if(strName.endsWith("_static"))
			extAttrList.put(strName.replaceAll("_static",""), strValue);
		else
			extAttrList.put(strName.toUpperCase(), strValue);
		
	}
	
	public void OnSetProperty(String strName, Object object)
	{
		if(arrListItem == null)
			arrListItem = new Hashtable();
		arrListItem.put(strName.toUpperCase(), strName);
		
		// 不明属性
		if (extAttrList == null)
			extAttrList = new LinkedHashMap();
		
		//_static 不转为大写 ,保持原大小写不变
		if(strName.endsWith("_static"))
			extAttrList.put(strName.replaceAll("_static",""), object);
		else
			extAttrList.put(strName.toUpperCase(), object);
	}
	
	public void FillAttributeBuilder(AttributeBuilder attributesBuilder){
		if(!StringHelper.IsNullOrEmpty(this.getId()))
			attributesBuilder.Set(TAG_ID,this.getId());
		
		if(!StringHelper.IsNullOrEmpty(this.getName()))
			attributesBuilder.Set(TAG_NAME,this.getName());
		
		if(!StringHelper.IsNullOrEmpty(this.getStyle()))
			attributesBuilder.Append(TAG_STYLE,this.getStyle());
		
		if(!StringHelper.IsNullOrEmpty(this.getCss()))
			attributesBuilder.Append(TAG_CSS,this.getCss());
		
		if(!StringHelper.IsNullOrEmpty(this.getWidth())){
			attributesBuilder.Set(TAG_WIDTH,strWidth);
		}
		
		if(!StringHelper.IsNullOrEmpty(this.getHeight()))
			attributesBuilder.Set(TAG_HEIGHT,this.getHeight());
	}
	
	/*
	* 判断是否存在指定键值
	 * @param strKey
	 * @return
	 */
	public boolean IsContainsKey(String strKey)
	{
		strKey = strKey.toUpperCase();
		if (extAttrList != null)
		{
			return extAttrList.containsKey(strKey);
		}
		return false;
	}

	/**
	 * @param strKey
	 * @param strDefault
	 * @return
	 */
	public String GetExtValue(String strKey, String strDefault)
	{
		strKey = strKey.toUpperCase();
		if (extAttrList != null)
			if (extAttrList.containsKey(strKey))
			{
				if(!StringHelper.IsNullOrEmpty((String) extAttrList.get(strKey))) return (String) extAttrList.get(strKey);
			}
		return strDefault;
	}

	/**
	 * @param strKey
	 * @param nDefault
	 * @return
	 */
	public int GetExtValue(String strKey, int nDefault)
	{
		try
		{
			Integer tempValue = new Integer(nDefault);
			return Integer.parseInt(GetExtValue(strKey, tempValue.toString()));
		}
		catch (Exception ex)
		{
			return nDefault;
		}
	}

	/**
	 * @param strKey
	 * @param nDefault
	 * @return
	 */
	public long GetExtValue(String strKey, long nDefault)
	{
		try
		{
			Long nTempValue = new Long(nDefault);
			return Long.parseLong(GetExtValue(strKey, nTempValue.toString()));
		}
		catch (Exception ex)
		{
			return nDefault;
		}

	}

	/**
	 * @param strKey
	 * @param bDefault
	 * @return
	 */
	public boolean GetExtValue(String strKey, boolean bDefault)
	{
		try
		{
			return Boolean.parseBoolean(GetExtValue(strKey, bDefault ? "True" : "False"));
		}
		catch (Exception ex)
		{
			return bDefault;
		}
	}

	/**
	 * 设置附加属性
	 * 
	 * @param strKey
	 * @param strValue
	 */
	public void SetExtValue(String strKey, String strValue)
	{
		if(arrListItem == null)
			arrListItem = new Hashtable();
		arrListItem.put(strKey.toUpperCase(), strKey);
		
		if (extAttrList == null)
			extAttrList = new LinkedHashMap();
		extAttrList.put(strKey.toUpperCase(), strValue);
	}

	/**
	 * 删除扩展属性
	 * @param strKey
	 */
	public void RemoveExtValue(String strKey)
	{
		if (extAttrList == null)
			return ;
		
		extAttrList.remove(strKey.toUpperCase());
	}
	
	
	public List<FormItem> getItems() {
		if(this.items == null)
			this.items = new ArrayList<FormItem>();
		return items;
	}
	
	public void addItem(FormItem item){
		if(this.items == null)
			this.items = new ArrayList<FormItem>();
		item.setParentItem(this);
		this.items.add(item);
	}
	
	public List<Script> getScript() {
		if(this.script == null)
			this.script = new ArrayList<Script>();
		return script;
	}
	
	public String getCss() {
		return this.strCss;
	}

	public String getId() {
		if(StringHelper.IsNullOrEmpty(this.strId))
			return this.strName;
		else
			return this.strId;
	}

	public String getName() {
		if(StringHelper.IsNullOrEmpty(this.strName))
			return this.strId;
		else
			return this.strName;
	}

	public String getStyle() {
		return this.strStyle;
	}

	public void setId(String strId) {
		this.strId = strId;
	}

	public void setName(String strName) {
		this.strName = strName;
	}

	public void setNodeName(String strNodeName) {
		this.strNodeName = strNodeName;
	}

	public void setStyle(String strStyle) {
		this.strStyle = strStyle;
	}

	public String getNodeName() {
		return strNodeName;
	}

	public void setCss(String strCss) {
		this.strCss = strCss;
	}

	public String getWidth() {
		return strWidth;
	}

	public void setWidth(String strWidth) {
		this.strWidth = strWidth;
	}

	public String getHeight() {
		return strHeight;
	}

	public void setHeight(String strHeight) {
		this.strHeight = strHeight;
	}

	public String getNodeValue() {
		return strNodeValue;
	}

	public void setNodeValue(String strNodeValue) {
		this.strNodeValue = strNodeValue;
	}
	
	public int getPos() {
		return iPos;
	}

	public void setPos(int pos) {
		iPos = pos;
	}
	
	public int getCurrentIndex() {
		return this.currentIndex;
	}
	
	public void setCurrentIndex(int index) {
		this.currentIndex = index;
	}
	
	public int getIndex() {
		return iIndex;
	}

	public void setIndex(int iIndex) {
		this.iIndex = iIndex;
	}
	
	public FormItem getParentItem() {
		return parentItem;
	}

	public void setParentItem(FormItem parentItem) {
		this.parentItem = parentItem;
	}
	
	public boolean isFromTag() {
		return bFromTag;
	}

	public void setFromTag(boolean bFromTag) {
		this.bFromTag = bFromTag;
	}
	
	public FormItem() {
		
	}

	public boolean isEnab() {
		return enab;
	}

	public void setEnab(boolean enab) {
		this.enab = enab;
	}

	public LinkedHashMap getExtAttrList() {
		return extAttrList;
	}
	public boolean isNoBody() {
		return bNoBody;
	}

	public void setNoBody(boolean bNoBody) {
		this.bNoBody = bNoBody;
	}
	
	public void spsnnv(String strKey,String strValue){
		if(StringHelper.IsNullOrEmpty(strValue))return;
		this.SetExtValue(strKey, strValue);
	}
	
	public void spsv(String strKey,String strValue){
		this.SetExtValue(strKey, strValue);
	}
	
	public void configItem(BaseDataEntity config){
		configItem(config,"default");
	}
	
	public void configItem(BaseDataEntity config,String action){
		if(config ==null)return;
		if("default".equals(action)){
			this.spsnnv("name", config.gpsv("name"));
			this.spsnnv("caption", config.gpsv("caption"));
			if(config.gpbv("required", false)){
				this.spsv("required","true");
			}
			this.spsnnv("colspan", config.gpsv("colspan"));
		}else if("table-static".equals(action)){
			this.spsnnv("name", config.gpsv("name"));
		}else if("table-dynamic".equals(action)){
			this.spsnnv("name", "e_"+config.gpsv("name"));
		}
	}
	
	public int getLev() {
		int lev = 0;
		FormItem item = this;
		while(item != null && item.getParentItem() != null){
			if(!StringHelper.IsNullOrEmpty(item.getParentItem().getNodeName())){
				lev ++;
			}
			item = item.getParentItem();
		}
		return lev;
	}

}
